package com.example.concurrency.exercise;

import java.util.Map;
import java.util.Random;
import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CyclicBarrier;

/**
 * @author: dangwen
 * @createDate: 2021/2/4
 */
public class CyclicBarrierDemo {
    /**
     * 存放子线程工作结果的容器
     */
    static ConcurrentHashMap<String,Long> resultMap
            = new ConcurrentHashMap<>();
    static CyclicBarrier cyclicBarrier = new CyclicBarrier(5,new BarrierActionThread(resultMap));
    public static void main(String[] args) {
//       CyclicBarrier cyclicBarrier = new CyclicBarrier(5);
        for (int i = 0; i < 5; i++) {
//            new Thread(new T1(cyclicBarrier)).start();
            new Thread(new T1(cyclicBarrier, resultMap)).start();
        }
    }

}

class T1 implements Runnable{

    private CyclicBarrier cyclicBarrier;
    private ConcurrentHashMap<String,Long> resultMap;
    public T1(CyclicBarrier cyclicBarrier,ConcurrentHashMap resultMap){
        this.cyclicBarrier = cyclicBarrier;
        this.resultMap = resultMap;
    }
    @Override
    public void run() {
        try {
            resultMap.put(Thread.currentThread().getName(), Thread.currentThread().getId());
            Random random = new Random();
            int nextInt = random.nextInt(10000);
            System.out.println(Thread.currentThread().getName()+"----------将要睡眠(ms)-------"+nextInt);
            Thread.sleep(nextInt);
            long currentTimeMillis = System.currentTimeMillis();
            cyclicBarrier.await();
            System.out.println(Thread.currentThread().getName()+"----------ready-------我等待了(ms)："+ (System.currentTimeMillis() - currentTimeMillis));
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (BrokenBarrierException e) {
            e.printStackTrace();
        }
    }
}

class BarrierActionThread implements Runnable{

    private ConcurrentHashMap<String,Long> resultMap;
    public BarrierActionThread(ConcurrentHashMap resultMap){
        this.resultMap = resultMap;
    }
    @Override
    public void run() {
        System.out.println("所有线程阻塞完成就会执行我！");
        try {
            StringBuilder result = new StringBuilder();
            for(Map.Entry<String,Long> workResult:resultMap.entrySet()){
                result.append("["+workResult.getValue()+"]");
            }
            System.out.println(result);
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("而我要执行完成，才会继续执行五个线程！");
    }
}
